﻿using System;
//Task 1 - Define a class Student, which contains data about a student – first, middle and last name, SSN, permanent address, 
//mobile phone e-mail, course, specialty, university, faculty. Use an enumeration for the specialties, universities and faculties.
//Override the standard methods, inherited by  System.Object: Equals(), ToString(), GetHashCode() and operators == and !=.

//Task 2 - Add implementations of the ICloneable interface. The Clone() method should deeply copy all object's fields 
//into a new object of type Student.

//Task 3 - Implement the  IComparable<Student> interface to compare students by names (as first criteria, in lexicographic order)
//and by social security number (as second criteria, in increasing order).


namespace ClassStudent
{
    public class Student : ICloneable
    {
        private string firstName;
        private string middleName;
        private string lastName;
        private string ssn;
        private string permanentAddress;
        private string mobilePhone;
        private string eMail;
        private byte? course;
        private Specialties specialty;
        private Faculties faculty;
        private Universities university;

        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }
        public string MiddleName
        {
            get { return middleName; }
            set { middleName = value; }
        }
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
        public string SSN
        {
            get { return ssn; }
            set { ssn = value; }
        }
        public string PermanentAddress
        {
            get { return permanentAddress; }
            set { permanentAddress = value; }
        }
        public string MobilePhone
        {
            get { return mobilePhone; }
            set { mobilePhone = value; }
        }
        public string EMail
        {
            get { return eMail; }
            set { eMail = value; }
        }
        public byte? Course
        {
            get { return course; }
            set { course = value; }
        }
        public Specialties Specialty
        {
            get { return specialty; }
            set { specialty = value; }
        }
        public Faculties Faculty
        {
            get { return faculty; }
            set { faculty = value; }
        }
        public Universities University
        {
            get { return university; }
            set { university = value; }
        }
        public Student(string firstName, string middleName, string lastName, string SSN, string mobilePhone = null,
            string email = null, byte? course = null, Specialties specialty = Specialties.Undefined,
            Universities university = Universities.Undefined, Faculties faculty = Faculties.Undefined)
        {
            this.FirstName = firstName;
            this.MiddleName = middleName;
            this.LastName = lastName;
            this.SSN = SSN;
            this.MobilePhone = mobilePhone;
            this.EMail = email;
            this.Course = course;
            this.Specialty = specialty;
            this.University = university;
            this.Faculty = faculty;
        }
        public override bool Equals(object obj)
        {
            Student other = obj as Student;

            if (other == null)
            {
                return false;
            }
            // Compare the reference type member fields
            if (!Object.Equals(this.SSN, other.SSN))
            {
                return false;
            }
            return true;
        }

        public static bool operator ==(Student firstStudent, Student secondStudent)
        {
            return Student.Equals(firstStudent, secondStudent);
        }

        public static bool operator !=(Student firstStudent, Student secondStudent)
        {
            return !(Student.Equals(firstStudent, secondStudent));
        }
        public override int GetHashCode()
        {
            //using only mandatory and not mutable fields to calculate hash code
            //so the hash code of the current student will ALWAYS be the same
            int hash = this.FirstName.GetHashCode()
                ^ this.MiddleName.GetHashCode()
                ^ this.LastName.GetHashCode()
                ^ this.SSN.GetHashCode();
            return hash;
        }

        public override string ToString()
        {
            string text = string.Format("Student: {0} {1} {2}       SSN: {3}\nStudies: {4}, {5}, {6}.",
                this.FirstName , this.MiddleName, this.LastName, this.SSN,
                this.Specialty, this.Faculty, this.University);
            return text;
        }
        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public Student Clone()
        {
            Student clonedStudent = new Student(this.FirstName, this.MiddleName, this.LastName, this.SSN, this.MobilePhone,
            this.EMail, this.Course, this.Specialty, this.University, this.Faculty);
            return clonedStudent;
        }
        public int CompareTo(Student other)
        {
            string thisFullName = this.FirstName + this.MiddleName + this.LastName;
            string studentFullName = other.FirstName + other.MiddleName + other.LastName;
            int result = thisFullName.CompareTo(studentFullName);
            if (result == 0)
            {
                result = this.SSN.CompareTo(other.SSN);
            }
            return result;
        }
    }
}
